package com.tianji.learning.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.QuestionAdminPageQuery;
import com.tianji.learning.domain.query.QuestionPageQuery;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.enums.QuestionStatus;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.service.IInteractionReplyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author mytjxt
 * @since 2024-05-27
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    final UserClient userClient;
    final SearchClient searchClient;
    final IInteractionReplyService replyService;
    final CatalogueClient catalogueClient;
    final CourseClient courseClient;
    final CategoryCache category;

    @Override
    public void saveQuestion(QuestionFormDTO questionDTO) {
        // 1.获取登录用户
        Long userId = UserContext.getUser();
        //2封装实体
        InteractionQuestion interactionQuestion
                = BeanUtils.copyBean(questionDTO, InteractionQuestion.class);
        //补充数据
        interactionQuestion.setUserId(userId);
        save(interactionQuestion);


    }

    @Override
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {
        //1.获取登录用户
        Long userId = UserContext.getUser();
        //2.分页查询
        Page<InteractionQuestion> questionPage = lambdaQuery()
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, userId)
                .eq(InteractionQuestion::getCourseId, query.getCourseId())
                .eq(query.getSectionId()!=null, InteractionQuestion::getSectionId, query.getSectionId())
                .eq(InteractionQuestion::getHidden, false)
                .page(query.toMpPage("create_time", false));
        List<InteractionQuestion> questions = questionPage.getRecords();
        if (CollUtils.isEmpty(questions)) {
            return PageDTO.empty(questionPage);
        }
        //3.封装返回
//        QuestionVO questionVO = new QuestionVO();
//        List<QuestionVO> questionVOS = BeanUtils.copyList(questions, QuestionVO.class);

        //3.1匿名处理
        //3.1.1远程调用用户服务-查询用户集合
        Set<Long> ids =new HashSet<>();
        Set<Long> answerIds = new HashSet<>();
        for (InteractionQuestion question : questions) {
            if (!question.getAnonymity()){
                Long id = question.getUserId();
                ids.add(id);
            }
                answerIds.add(question.getLatestAnswerId());
        }
        //去除null，因为有些问题没有回答者
        answerIds.remove(null);
        //3.2最近一次回答
  HashMap<Long, InteractionReply> rMap = new HashMap<>();
        if (!answerIds.isEmpty()){

            List<InteractionReply>
                    replies =
            replyService.lambdaQuery()
                    .in(InteractionReply::getId, answerIds)
                    .eq(InteractionReply::getHidden,false)
                    .list();
            //3.2.1把回复信息封装成map
            for (InteractionReply reply : replies) {

                rMap.put(reply.getId(),reply);
                //取出回答者的用户id
                Long userId1 = reply.getUserId();
                ids.add(userId1);
            }
        }


        ids.remove(null);
        List<UserDTO> users = userClient.queryUserByIds(ids);
        //3.1.2把提问者的用户信息封装成map
        Map<Long, UserDTO> userMap = new HashMap<>();
        users.forEach(user -> {
            userMap.put(user.getId(),user);
        });

        //把回答者的用户信息封装成map
        //3.3最近一次回答的用户信息
        List<QuestionVO> questionVOS = new ArrayList<>();
        for (InteractionQuestion question : questions) {
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(question, questionVO);
            //查询提问者用户信息
            if (!questionVO.getAnonymity()){
                questionVO.setUserName(userMap.get(questionVO.getUserId()).getUsername());
                questionVO.setUserIcon(userMap.get(questionVO.getUserId()).getIcon());
            }
            //最新的回答信息
            if (rMap.size()>0){
            questionVO.setLatestReplyContent(rMap.get(question.getLatestAnswerId()).getContent());
            }
            //最新的回答者昵称
            //查询回答者用户信息
            if (rMap.size()>0){
            if (!rMap.get(question.getLatestAnswerId()).getAnonymity()){
                questionVO.setLatestReplyUser(userMap.get(rMap.get(question.getLatestAnswerId()).getUserId()).getUsername());
            }
            }
            questionVOS.add(questionVO);

        }





        return PageDTO.of(questionPage, questionVOS);
    }

    @Override
    public QuestionVO queryQuestionById(Long id) {
        InteractionQuestion question = lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .eq(InteractionQuestion::getHidden, false).one();
        if (question == null){
            return null;
        }
        QuestionVO questionVO = BeanUtils.copyProperties(question, QuestionVO.class);
      if (!questionVO.getAnonymity()) {
          UserDTO userDTO = userClient.queryUserById(questionVO.getUserId());
          if (userDTO != null){
          questionVO.setUserName(userDTO.getName());
          questionVO.setUserIcon(userDTO.getIcon());
      }}
        return questionVO;
    }

    @Override
    public boolean deleteMyQuestionById(Long id) {
        //只能删除自己的提的问题
        //获取登录用户
        Long userId = UserContext.getUser();

        //1.先查询问题
        InteractionQuestion question = lambdaQuery().eq(InteractionQuestion::getId, id).one();
        if (question == null){
            throw new BadRequestException("问题不存在");
        }
        //2.判断是否是本人
      if(!question.getUserId().equals(userId)){
          throw new BizIllegalException("只能删除自己的提问");

      }
        removeById(id);
        //  删除问题下的回答及评论
        LambdaQueryWrapper<InteractionReply> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InteractionReply::getQuestionId, question.getId());
        replyService.remove(wrapper);
        return false;
    }

    @Override
    public PageDTO<QuestionAdminVO> queryQuestionPageAdmin(QuestionAdminPageQuery query) {
        //0.根据课程名称查询课程id
        List<Long> courseIds=null;
        if (query.getCourseName() != null){
         courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
        }
        //1.写sql
        Page<InteractionQuestion> questionPage = lambdaQuery()
                .in(CollUtils.isNotEmpty(courseIds), InteractionQuestion::getCourseId, courseIds)
                .eq(query.getStatus() != null, InteractionQuestion::getStatus, query.getStatus())
                .ge(query.getBeginTime() != null, InteractionQuestion::getCreateTime, query.getBeginTime())
                .le(query.getEndTime() != null, InteractionQuestion::getCreateTime, query.getEndTime())
                .page(query.toMpPage("create_time", false));

        List<InteractionQuestion> records = questionPage.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(questionPage);
        }
        //2封装
        //2.1根据章、节id获取章、节名称
       List<Long> chapterAndSectionIds =new ArrayList<>();
        for (InteractionQuestion record : records) {
            chapterAndSectionIds.add(record.getChapterId());
            chapterAndSectionIds.add(record.getSectionId());
        }
        List<CataSimpleInfoDTO> dtos = catalogueClient.batchQueryCatalogue(chapterAndSectionIds);
        Map<Long, String> map =
                dtos.stream()
                        .collect(Collectors.toMap(CataSimpleInfoDTO::getId,CataSimpleInfoDTO::getName));
        //2.2根据课程id获取课程名称
        List<CourseSimpleInfoDTO> simpleInfoList = courseClient.getSimpleInfoList(courseIds);
        Map<Long, String> courseMap = simpleInfoList.stream()
                .collect(Collectors.toMap(CourseSimpleInfoDTO::getId, CourseSimpleInfoDTO::getName));
        //2.3根据课程所在一二三级别分类获取分类名称--用caffine缓存
        List<String> categoryNames = new ArrayList<>();
        for (CourseSimpleInfoDTO dto : simpleInfoList) {
           String categoryName = category.getCategoryNames(dto.getCategoryIds());
           categoryNames.add(categoryName);
        }
       //map （课程id，分类名称）
        Map<Long, String> categoryNameMap = new HashMap<>();
        for (int i = 0; i < simpleInfoList.size(); i++) {
            categoryNameMap.put(simpleInfoList.get(i).getId(),categoryNames.get(i));
        }

        //2.4获取提问者昵称
        List<Long> userIds = records.stream().map(InteractionQuestion::getUserId).collect(Collectors.toList());
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        Map<Long, String> userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO::getUsername));
        //3.返回
        List<QuestionAdminVO> questionAdminVOS = new ArrayList<>();
        for (InteractionQuestion record : records) {
            QuestionAdminVO vo = BeanUtils.copyProperties(record, QuestionAdminVO.class);
              vo.setChapterName(map.get(record.getChapterId()));
            vo.setSectionName(map.get(record.getSectionId()));
            vo.setCourseName(courseMap.get(record.getCourseId()));
            vo.setCategoryName(categoryNameMap.get(record.getCourseId()));
            vo.setUserName(userMap.get(record.getUserId()));
            questionAdminVOS.add(vo);
        }

        return PageDTO.of(questionPage, questionAdminVOS);
    }

    @Override
    public boolean updateHiddenById(Long id, Boolean hidden) {
      // 查询问题是否存在
        InteractionQuestion question = getById(id);
        if (question == null){
            throw new BadRequestException("问题不存在");
        }
        // 更新隐藏字段
        question.setHidden(hidden);
        return this.updateById(question);
    }

    @Override
    public QuestionAdminVO detailAdmin(Long id) {

        if (id == null) {
            throw new BadRequestException("参数有误");
        }
        InteractionQuestion question = getById(id);
        if (question == null) {
            throw new BadRequestException("问题不存在");
        }

        // 拷贝实体类
        QuestionAdminVO questionVO = BeanUtils.copyBean(question, QuestionAdminVO.class);
        if (!question.getAnonymity()) { // 用户信息
            UserDTO userDTO = userClient.queryUserById(question.getUserId());
            if (userDTO != null) {
                questionVO.setUserName(userDTO.getName());  // 用户名称
                questionVO.setUserIcon(userDTO.getIcon());  // 用户头像
            }
        }
        // 查询课程信息
        CourseFullInfoDTO courseInfo = courseClient.getCourseInfoById(question.getCourseId(), true, true);
        if (courseInfo == null) {
            throw new BadRequestException("课程不存在");
        }
        questionVO.setCourseName(courseInfo.getName()); // 课程名称
        questionVO.setCategoryName(category.getCategoryNames(courseInfo.getCategoryIds())); // 课程三级分类名称
        // 根据教师id列表去用户表查询
        List<UserDTO> teacherDTOS = userClient.queryUserByIds(courseInfo.getTeacherIds());
        if (!CollUtil.isEmpty(teacherDTOS)){
            // 拼接教师名称，形如：教师A/教师B/教师C
            StringBuilder teacherName = new StringBuilder();
            for(UserDTO userDTO: teacherDTOS){
                teacherName.append(userDTO.getName() + "/");
            }
            // 删掉最后一个斜杆
            teacherName.deleteCharAt(teacherName.length()-1);
            questionVO.setTeacherName(teacherName.toString());  // 课程负责教师名称
        }
        // 拼接考试名称
        // 查询章节信息
        List<CataSimpleInfoDTO> catalogueDTOs = catalogueClient
                .batchQueryCatalogue(List.of(question.getChapterId(), question.getSectionId()));
        if (!CollUtil.isEmpty(catalogueDTOs)) { // 列表不为空
            Map<Long, String> cataMap = catalogueDTOs.stream()
                    .collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
            questionVO.setChapterName(cataMap.getOrDefault(question.getChapterId(),""));    // 章节名称
            questionVO.setSectionName(cataMap.getOrDefault(question.getSectionId(),""));    // 小节名称

        }
        // 更新问题为已查看
        question.setStatus(QuestionStatus.CHECKED);
        this.updateById(question);
        // 返回结果
        return questionVO;
    }


}
